﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Diagnostics;
using System.IO;
using System.Resources;
using System.Reflection;
using System.Xml;
using System.Xml.Serialization;
using System.Text;

using Microsoft.BizTalk.Bam.EventObservation;
using Microsoft.BizTalk.Message.Interop;
using Microsoft.BizTalk.Component.Interop;
using Microsoft.BizTalk.Streaming;
using Microsoft.BizTalk.XPath;

using Software41.Tracking.BAM;
using Software41.Tracking.BAM.Adapters;
using Software41.TrackingExample.Components;

namespace Software41.TrackingExample.PipelineComponents
{
    [ComponentCategory(CategoryTypes.CATID_PipelineComponent)]
    [System.Runtime.InteropServices.Guid("A8A7CFBF-F317-4a14-BED7-141CA49B64EA")]
    [ComponentCategory(CategoryTypes.CATID_Any)]
    public partial class ArchiveMessage :
                           IBaseComponent,
                            IComponentUI,
                            Microsoft.BizTalk.Component.Interop.IComponent,
                            IPersistPropertyBag
    {
        #region Private Properties
        private ResourceManager resourceManager =
           new ResourceManager("Software41.TrackingExample.PipelineComponents.ArchiveMessage", Assembly.GetExecutingAssembly());

        #endregion
        #region Configuration Properties

        private string _fileName;
        public string FileName
        {
            get
            {
                return _fileName;
            }
            set
            {
                _fileName = value;
            }
        }

        private string _fileNameNamespace;
        public string FileNameNamespace
        {
            get
            {
                return _fileNameNamespace;
            }
            set
            {
                _fileNameNamespace = value;
            }
        }

        private string _archivePath;
        public string ArchivePath
        {
            get
            {
                return _archivePath;
            }
            set
            {
                _archivePath = value;
            }
        }

        private bool _archiveFiles;
        public bool ArchiveFiles
        {
            get
            {
                return _archiveFiles;
            }
            set
            {
                _archiveFiles = value;
            }
        }

        #endregion 

        #region IBaseComponent members
        /// <summary> 
        /// Name of the component 
        /// </summary> 
        [Browsable(false)]
        public string Name
        {
            get
            {
                return resourceManager.GetString("COMPONENTNAME", System.Globalization.CultureInfo.InvariantCulture);
            }
        }

        /// <summary> 
        /// Version of the component 
        /// </summary> 
        [Browsable(false)]
        public string Version
        {
            get
            {
                return resourceManager.GetString("COMPONENTVERSION", System.Globalization.CultureInfo.InvariantCulture);
            }
        }

        /// <summary> 
        /// Description of the component 
        /// </summary> 
        [Browsable(false)]
        public string Description
        {
            get
            {
                return resourceManager.GetString("COMPONENTDESCRIPTION", System.Globalization.CultureInfo.InvariantCulture);
            }
        }
        #endregion 

        #region IComponentUI
        [Browsable(false)]
        public IntPtr Icon
        {
            get
            {
                return ((System.Drawing.Bitmap)(this.resourceManager.GetObject("COMPONENTICON", System.Globalization.CultureInfo.InvariantCulture))).GetHicon();
            }
        }


        public System.Collections.IEnumerator Validate(object projectSystem)
        {
            return null;
        }
        #endregion

        #region IPersistPropertyBag
        public void GetClassID(out Guid classID)
        {
            classID = new Guid("85B141A5-B360-41ff-837D-E25E713B04C0");
        }

        public void InitNew()
        {
            throw new NotImplementedException();
        }

        public void Load(IPropertyBag propertyBag, int errorLog)
        {
            object val = this.ReadPropertyBag(propertyBag, "FileName");

            if (val != null)
            {
                this.FileName = (string)val;
            }

            val = this.ReadPropertyBag(propertyBag, "FileNameNamespace");

            if (val != null)
            {
                this.FileNameNamespace = (string)val;
            }

            val = this.ReadPropertyBag(propertyBag, "ArchivePath");

            if (val != null)
            {
                this.ArchivePath = (string)val;
            }

            val = this.ReadPropertyBag(propertyBag, "ArchiveFiles");

            if (val != null)
            {
                this.ArchiveFiles = (bool)val;
            }
        }

        public void Save(IPropertyBag propertyBag, bool clearDirty, bool saveAllProperties)
        {
            this.WritePropertyBag(propertyBag, "FileName", this.FileName);
            this.WritePropertyBag(propertyBag, "FileNameNamespace", this.FileNameNamespace);
            this.WritePropertyBag(propertyBag, "ArchivePath", this.ArchivePath);
            this.WritePropertyBag(propertyBag, "ArchiveFiles", this.ArchiveFiles);
        }
        #endregion

        #region IComponent members
        /// <summary> 
        /// Implements IComponent.Execute method. 
        /// </summary> 
        /// <param name="pc">Pipeline context</param> 
        /// <param name="inmsg">Input message</param> 
        /// <returns>Original input message</returns> 
        /// <remarks> 
        /// IComponent.Execute method is used to initiate 
        /// the processing of the message in this pipeline component. 
        /// </remarks> 
        public Microsoft.BizTalk.Message.Interop.IBaseMessage Execute(Microsoft.BizTalk.Component.Interop.IPipelineContext pc, Microsoft.BizTalk.Message.Interop.IBaseMessage inmsg)
        {
            if (this._archiveFiles)
            {
                string archiveFileName = inmsg.Context.Read(this._fileName, this._fileNameNamespace) as string;
                if (archiveFileName != null && !string.IsNullOrEmpty(archiveFileName))
                {
                    if (archiveFileName.Contains("\\"))
                        archiveFileName = archiveFileName.Substring(archiveFileName.LastIndexOf("\\") + 1);

                    ArchivingStream archivingStream = new ArchivingStream(inmsg.BodyPart.Data, this._archivePath + "\\" + archiveFileName);
                    pc.ResourceTracker.AddResource(archivingStream);
                    inmsg.BodyPart.Data = archivingStream;
                }
            }
            return inmsg;
        }
        #endregion 

        #region utility functionality
        /// <summary> 
        /// Reads property value from property bag 
        /// </summary> 
        /// <param name="pb">Property bag</param> 
        /// <param name="propName">Name of property</param> 
        /// <returns>Value of the property</returns> 
        private object ReadPropertyBag(Microsoft.BizTalk.Component.Interop.IPropertyBag pb, string propName)
        {
            object val = null;
            try
            {
                pb.Read(propName, out val, 0);
            }
            catch (System.ArgumentException)
            {
                return val;
            }
            catch (System.Exception e)
            {
                throw new System.ApplicationException(e.Message);
            }
            return val;
        }

        /// <summary> 
        /// Writes property values into a property bag. 
        /// </summary> 
        /// <param name="pb">Property bag.</param> 
        /// <param name="propName">Name of property.</param> 
        /// <param name="val">Value of property.</param> 
        private void WritePropertyBag(Microsoft.BizTalk.Component.Interop.IPropertyBag pb, string propName, object val)
        {
            try
            {
                pb.Write(propName, ref val);
            }
            catch (System.Exception e)
            {
                throw new System.ApplicationException(e.Message);
            }
        }
        #endregion 

    }
}
